package com.asa.a;


/**
 * String
 * 在java中它是一种很特别的存在
 * 
 * 
 * @author Administrator
 *
 */
public class O {
	
	
	/**
	 * 
	 * String的基本特性
		String:字符串，使用一对""引起来表示
		●String声明为final的，不可被继承
		)● String实现了Serializable接口:表示字符串是支持序列化的。
		实现了Comparable接口:表示String可以比较大小
		String在jdk8及以前内部定义了final char[] value用 于存储字
		符串数据。jdk9时改为byte[]

	 * 
	 * 
	 * 
	 * 
	 * 字符串常量池中是不会存储租同内容的子符串的。
		➢String的String Pool是一个固定大小的Hashtable,默认值大小长度
		是1009。如果放进String Poo1的String非常 多，就会造成Hash冲突
		严重，从而导致链表会很长，而链表长了后直接会造成的影响就是当调用
		String. intern时性能会大幅下降。
		➢使用-Xx: StringTableSize可设置StringTable的长度
		➢在jdk6中StringTable是固定的，就是1009的长度，所以如果常量池中
		的字符串过多就会导致效率下降很快。StringTableSize设置没有要求
		➢在jdk7中，StringTable的长度默认值是60013，1009是 可设置的最小
		值。

	 * 
	 * 
	 * 
	 * 在Java语言中有8种基本数据类型和一种比较特殊的类型String。这些
		类型为了使它们在运行过程中速度更快、更节省内存，都提供了一种常
		量池的概念。
		常量池就类似一个Java系统级别提供的缓存。8种基本数据类型的常量
		池都是系统协调的，String类 型的常量池比较特殊。它的主要使用方法
		有两种。
		。
		➢直接使用双引号声明出来的String对象会直接存储在常量池中。
		V比如: String info = "atguigu. com";| I
		➢如果不是用双引号声明的String对象，可以使用String提供的
		intern()方法。这个后面重点谈

	 * 
	 * 
	 * 
	 * ●Java 6及以前，字符串常量池存放在永久代。
			Java 7中Oracle 的工程师对字符串池的逻辑做了很大的改变，即将
			字符串常量池的位置调整到Java堆内。
			➢所有的字符串都保存在堆(Heap)中，和其他普通对象一样，这样
			可以让你在进行调优应用时仅需要调整堆大小就可以了。
			➢字符串常量池概念原本使用得比较多，但是这个改动使得我们有足够
			的理由让我们重新考虑在Java 7中使用String. intern()。
			|●
			Java8元空间，字符串常量在堆

	 * 
	 * 
	 * 
	 * 
	 * 
		字符串拼接操作
		1.常量与常量的拼接结果在常量池，原理是编译期优化
		2.常量池中不会存在相同内容的常量。
		3.只要其中有一一个是变量，结果就在堆中。变量拼接的原理是StringBuilder
		4.如果拼接的结果调用intern()方法，则主动将常量池中还没有的字符串对象
		放入池中，并返回此对象地址。

	 * 
	 * 
	 * 
	 * 
	 * 
	 * intern()的使用
			如果不是用双引号声明的String对象，可以使用string提供的intern方法: intern
			方法会从字符串常量池中查询当前字符串是否存在，若不存在就会将当前字符串放入常
			量池中。.
			●比如: String myInfo = new String("I love atguigu"). intern() ;
			也就是说，如果在任意字符串上调用String. intern方法，那么其返回结果所指向的
			。那个类实例，必须和直接以常量形式出现的字符串实例完全相同。因此，下 列表达式的
			值必定是true: .
			("a" + "b" + "c") . intern () == "abc"
			通俗点讲，Interned String就 是确保字符串在内存里只有一-份拷贝，这样可以节约
			内存空间，加快字符串操作任务的执行速度。注意，这个值会被存放在字符串内部池
			(String Intern Pool) 。

	 * 
	 * 
	 * new String("abc")会创建几个对象？
	 * 		两个new会有一个在堆上，"abc"在常量池中，当然，如果之前常量池中有"abc"这个字符串，那又只能说一个对象了
	 * 		看字节码可以知道
	 * 
	 * 
	 * 
	 * 
	 * new String("a") + new String("b") 呢？
	 * 		StringBuild
	 * 		new String
	 * 		"a"
	 * 		new String
	 * 		"b"
	 * 		StringBuild.toString 还会创建对象
	 * 			new String
	 * 			"ab"没有在字符串常量池中
	 * 
	 * 		6个对象
	 * 		
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 总结String的intern()的使用:
			●jdk1.6中，将这个字符串对象尝试放入串池。
			➢如果串池中有，则并不会放入。返回已有的串池中的对象的地址
			➢如果没有，会把此对象复制一份，放入串池，并返回串池中的对
			象地址
			●Jdk1.7起，将这个字符串对象尝试放入串池。
			➢如果串池中有，则并不会放入。返回已有的串池中的对象的地址
			➢如果没有，则会把对象的引用地址复制一-份，放入串池，并返回
			串池中的引用地址

	 * 
	 * 
	 * ●背景:对许多Java应用(有大的也有小的D做的测试得出以下结果:
			➢堆存活数据集合里面string对象占了25号
			➢堆存活数据集合里面重复的String对象有13.5号
			➢String对象的平均长度是45
			)●
			许多大规模的Java应用的瓶颈在于内存，测试表明，在这些类型的应用(
			里面，Java堆中存活的数据集合差不多258是String对象。更进一步，
			这里面差不多一半string对 象是重复的，重复的意思是说:
			string1. equals (string2)=true。堆上存在重复的String对象必
			然是一种内存的浪费。这个项目将在G1垃圾收集器中实现自动持续对重
			复的string对象进行去重，这样就能避免浪费内存。
	 * 
	 * 
	 * 实现
			➢当垃圾收集器工作的时候，会访问堆上存活的对象。对每一个访问的对象都会
			检查是否是候选的要去重的String对象。
			➢如果是，把这个对象的一个引用插入到队列中等待后续的处理。--个去重的线
			程在后台运行，处理这个队列。处理队列的一个元素意味着从队列删除这个元
			素，然后尝试去重它引用的String对象。
			➢使用一个hashtable来记录所有的被string对象使用的不重复的char数组。
			当去重的时候，会查这个hashtable，来看堆上是否已经存在一个一模一样的
			char数组。
			➢如果存在，String对象会被调整引用那个数组，释放对原来的数组的引用，最
			终会被垃圾收集器回收掉。
			➢如果查找失败，char 数组会被插入到hashtable，这样以后的时候就可以共
			享这个数组了。

	 * 
	 * 
	 * 
	 * 
	 * 
	 */
	
	
	
	

}
